﻿using System;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace IceDog.SmallProject.SystemTextJson
{
    class Program
    {
        private static WeatherForecast weatherForecast = new WeatherForecast()
        {
            Date = DateTime.Now,
            Summary = "today is nice",
            TemperatureC = 26
        };

        private static string weatherForecastText = Serialize(weatherForecast);
        private static string weatherForecastArrStr = "[" +
                "{" +
                    "\"date\": \"2013-01-07T00:00:00Z\"," +
                    "\"temp\": 23," +
                "}," +
                "{" +
                    "\"date\": \"2013-01-08T00:00:00Z\"," +
                    "\"temp\": 28," +
                "}," +
                "{" +
                    "\"date\": \"2013-01-14T00:00:00Z\"," +
                    "\"temp\": 8," +
                "}," +
            "]";
        static void Main(string[] args)
        {
            //序列化测试
            SerializeTest();
            //序列化格式化测试
            //SerializeIndentedTest();
            //反序列化测试
            //DeserializeTest();
            //异步反序列化测试
            //DeserializeAsyncTest();
            //反序列化解析json字符串测试
            //ComputeAverageTemperaturesOfMondayTest();
            //使用JsonWriter JsonReader测试
            //UseJsonWriterJsonReaderWithTokenTest();
        }
        #region 测试
        private static void UseJsonWriterJsonReaderWithTokenTest()
        {
            //使用jsonwriter写入数据
            string wResult = UseJsonWriter();
            Console.WriteLine("JsonWriter 生成的json字符串");
            Console.WriteLine(wResult);

            Console.WriteLine("");
            UseJsonReaderWithToken(weatherForecastArrStr);
        }

        private static void ComputeAverageTemperaturesOfMondayTest()
        {
            byte[] wfDataBytes = UTF8Encoding.Default.GetBytes(weatherForecastArrStr);
            var avgTemp = ComputeAverageTemperaturesOfMonday(wfDataBytes);
            Console.WriteLine($"Average Temperatures Of Monday:{avgTemp}");
        }

        private static void DeserializeAsyncTest()
        {
            WeatherForecast weatherForecastA = DeserializeAsync(new MemoryStream(UTF8Encoding.Default.GetBytes(weatherForecastText))).Result;
            Console.WriteLine(weatherForecastA.Summary);
        }

        private static void DeserializeTest()
        {
            WeatherForecast weatherForecastA = Deserialize(weatherForecastText);
            Console.WriteLine(weatherForecastA.Summary);
        }

        private static void SerializeIndentedTest()
        {
            string result = SerializeIndented(weatherForecast);
            Console.WriteLine(result);
        }


        private static void SerializeTest()
        {
            string result = Serialize(weatherForecast);
            Console.WriteLine(result);
        }
        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="weatherForecast"></param>
        /// <returns></returns>

        static string Serialize(WeatherForecast weatherForecast)
        {
            return JsonSerializer.Serialize(weatherForecast);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="weatherForecast"></param>
        /// <returns></returns>
        static string SerializeIndented(WeatherForecast weatherForecast)
        {
            return JsonSerializer.Serialize<WeatherForecast>(weatherForecast, new JsonSerializerOptions()
            {
                WriteIndented = true
            });

        }
        static WeatherForecast Deserialize(string json)
        {
            var options = new JsonSerializerOptions
            {
                AllowTrailingCommas = true//允许尾巴有多余逗号
            };

            return JsonSerializer.Deserialize<WeatherForecast>(json, options);
        }

        async static Task<WeatherForecast> DeserializeAsync(Stream json)
        {
            var options = new JsonSerializerOptions
            {
                AllowTrailingCommas = true//允许尾巴有多余逗号
            };

            return await JsonSerializer.DeserializeAsync<WeatherForecast>(json, options);
        }

        static double ComputeAverageTemperaturesOfMonday(byte[] bytes)
        {
            System.Buffers.ReadOnlySequence<byte> readOnlySequence = new System.Buffers.ReadOnlySequence<byte>(bytes);
            var options = new JsonDocumentOptions
            {
                AllowTrailingCommas = true,
                CommentHandling = JsonCommentHandling.Skip,
                MaxDepth = 3,
            };
            using (JsonDocument document = JsonDocument.Parse(readOnlySequence, options))
            {
                int sumOfAllTemperatures = 0;
                int count = 0;

                foreach (JsonElement element in document.RootElement.EnumerateArray())
                {
                    DateTimeOffset date = element.GetProperty("date").GetDateTimeOffset();

                    if (date.DayOfWeek == DayOfWeek.Monday)
                    {
                        int temp = element.GetProperty("temp").GetInt32();
                        sumOfAllTemperatures += temp;
                        count++;
                    }
                }

                var averageTemp = (double)sumOfAllTemperatures / count;
                return averageTemp;
            }
        }

        static string UseJsonWriter()
        {
            var options = new JsonWriterOptions
            {
                Indented = true
            };
            Random ran = new Random();
            using (var stream = new MemoryStream())
            {
                using (var writer = new Utf8JsonWriter(stream, options))
                {
                    writer.WriteStartObject();
                    writer.WriteString("date", DateTimeOffset.UtcNow);
                    writer.WriteNumber("temp", ran.Next(10, 42));
                    writer.WriteEndObject();
                }

                string json = Encoding.UTF8.GetString(stream.ToArray());
                return json;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="json"></param>
        static void UseJsonReaderWithToken(string json)
        {
            byte[] data = Encoding.UTF8.GetBytes(json);
            Utf8JsonReader reader = new Utf8JsonReader(data, isFinalBlock: true,
                state: new JsonReaderState(new JsonReaderOptions()
                {
                    AllowTrailingCommas = true//允许尾部有逗号
                }));
            while (reader.Read())
            {
                Console.WriteLine("Token Type :"+reader.TokenType);

                switch (reader.TokenType)
                {
                    case JsonTokenType.PropertyName:
                    case JsonTokenType.String:
                        {
                            string text = reader.GetString();
                            Console.Write(" ");
                            Console.Write(text);
                            break;
                        }

                    case JsonTokenType.Number:
                        {
                            int value = reader.GetInt32();
                            Console.Write(" ");
                            Console.Write(value);
                            break;
                        }
                }
                Console.WriteLine();
            }
        }
    }
}
